package com.ltxtiyu.video.service.impl;

import com.alibaba.dubbo.config.annotation.Service;

import com.ltxtiyu.video.dao.ltx.HotWordDao;
import com.ltxtiyu.video.entity.HotWord;
import com.ltxtiyu.video.service.ms.SearchService;
import com.ltxtiyu.video.tool.StringUtil;
import com.ltxtiyu.video.vo.ms.HotWordVo;
import com.ltxtiyu.video.vo.ms.NumberVO;
import com.ltxtiyu.video.vo.ms.SearchVO;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.*;

@Service
public class SearchServiceImpl implements SearchService {


    private String index ="l_search_log_index";

    @Autowired
    private HotWordDao hotWordDao;

    @Autowired
    TransportClient client;

    @Override
    public Map<String, Object> selectParamList(Map<String, Object> map) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date dateBefore3 = getDateBefore(new Date(), 3);
        Date dateBefore7 = getDateBefore(new Date(), 7);
        int count = hotWordDao.findByParamCount(map);
        List<HotWordVo> data= hotWordDao.findByParamList(map);
        if (data!= null &&data.size()>0){


            for (HotWordVo hotWordVo:data){
                //查询总量
                SearchResponse totalResp = client.prepareSearch(index)
                        .setQuery(QueryBuilders.termQuery("word_name", hotWordVo.getName())).get();
                long searchCount = totalResp.getHits().getTotalHits();
                hotWordVo.setSearchCount(searchCount);
                //查询前3天
                SearchResponse threedayResp = client.prepareSearch(index).setQuery(QueryBuilders.boolQuery()
                        .must(QueryBuilders.termQuery("word_name", hotWordVo.getName()))
                        .must(QueryBuilders.rangeQuery("create_time").gte(format.format(dateBefore3.getTime())))

                ).get();
                long searchTimeIn3Day = threedayResp.getHits().getTotalHits();
                hotWordVo.setSearchTimeIn3Day(searchTimeIn3Day);
                //查询前7天
                SearchResponse sevendayResp = client.prepareSearch(index).setQuery(QueryBuilders.boolQuery()
                        .must(QueryBuilders.termQuery("word_name", hotWordVo.getName()))
                        .must(QueryBuilders.rangeQuery("create_time").gte(format.format(dateBefore7.getTime())))

                ).get();
                long searchTimeIn7Day = sevendayResp.getHits().getTotalHits();
                hotWordVo.setSearchTimeIn7Day(searchTimeIn7Day);
            }
        }

        Map<String,Object> result = new HashMap<>();
        result.put("code",0);
        result.put("msg","");
        result.put("count",count);
        result.put("data",data);
        return result;
    }

    @Override
    public void delByID(Integer id) {
        int i = hotWordDao.deleteByPrimaryKey(id);
    }

    @Override
    public void insert(HotWord hotWord) {
        HotWord record =  hotWordDao.findByName(hotWord.getName());
        if (record == null){

            hotWord.setCreateTime(new Date());

            int i = hotWordDao.insertSelective(hotWord);
        }
    }

    @Override
    public Map<String, Object> searchList(int page, int limit, String word, String name, Date startData, Date endData, Integer userId) throws ParseException {


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

        SearchResponse searchResponse = null;
        SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.rangeQuery("user_id").gt(0));

        if ( userId!= null &&userId>0){
            boolQueryBuilder.must(QueryBuilders.matchQuery("user_id",userId));

        }

        if (StringUtil.isNotBlank(word)){
            boolQueryBuilder.must(QueryBuilders.matchQuery("word_name", word));
        }

        if (StringUtil.isNotBlank(name)){
            boolQueryBuilder.must(QueryBuilders.matchQuery("nick_name", name));
        }
        if (startData!= null){
            boolQueryBuilder.must(QueryBuilders.rangeQuery("create_time").gte(startData.getTime()));
        }

        if (endData != null){
            boolQueryBuilder.must(QueryBuilders.rangeQuery("create_time").lte(endData.getTime()));
        }

        //排序与分页
        searchRequestBuilder.setFrom((page-1)*limit).setSize(limit);
        searchRequestBuilder.addSort("create_time", SortOrder.DESC);

        if (StringUtil.isNullOrEmpty(word)&&StringUtil.isNullOrEmpty(name)&&startData==null&&endData ==null&&userId==null){
            BoolQueryBuilder builder = QueryBuilders.boolQuery();
            builder.must(QueryBuilders.rangeQuery("user_id").gt(0));
            builder.must(QueryBuilders.matchAllQuery());
            searchResponse = searchRequestBuilder.setQuery(builder).get();
        }else {
            searchResponse = searchRequestBuilder.setQuery(boolQueryBuilder).get();
        }
        SearchHits hits = searchResponse.getHits();
        long count = hits.getTotalHits();
        Iterator<SearchHit> iterator = hits.iterator();
        List<SearchVO> data = new  ArrayList<>();
        while(iterator.hasNext()){
            SearchHit searchHit = iterator.next();
            Map<String, Object> source = searchHit.getSourceAsMap();
            SearchVO searchVO = new SearchVO();
            searchVO.setNickName((String) source.get("nick_name"));
            searchVO.setWord((String) source.get("word_name"));
            searchVO.setUserID((Integer)source.get("user_id"));
            Date create_time = format.parse((String) source.get("create_time"));
            Calendar cal = Calendar.getInstance();
            cal.setTime(create_time);
            cal.add(Calendar.HOUR_OF_DAY,8);
            SimpleDateFormat formatCal = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            searchVO.setCreateTime( formatCal.parse(formatCal.format(cal.getTime())));
            data.add(searchVO);
        }

        Map<String,Object> result = new HashMap<>();
        result.put("code",0);
        result.put("msg","");
        result.put("count",count);
        result.put("data",data);
        return result;
    }

    @Override
    public Map<String, Object> todayHotSearch() {
        SearchRequestBuilder requestBuilder = client.prepareSearch(index).setQuery(QueryBuilders.matchAllQuery());
        requestBuilder.addAggregation(AggregationBuilders.terms("hotword").field("word_name").size(10));
        SearchResponse searchResponse = requestBuilder.execute().actionGet();
        List<NumberVO> data= new ArrayList<>();
        Map<String, Aggregation> aggMap = searchResponse.getAggregations().asMap();
        long count = searchResponse.getHits().getTotalHits();
        if (aggMap != null){

            StringTerms teamAgg= (StringTerms) aggMap.get("hotword");
            Iterator<StringTerms.Bucket> teamBucketIt = teamAgg.getBuckets().iterator();
            while (teamBucketIt .hasNext()) {
                StringTerms.Bucket buck = teamBucketIt.next();

                String team = (String) buck.getKey();
                long amount = buck.getDocCount();
                NumberVO number = new NumberVO();
                number.setName(team);
                number.setCount(amount);
                data.add(number);
            }
        }
        Map<String,Object> result = new HashMap<>();
        result.put("code",0);
        result.put("msg","");
        result.put("count",count);
        result.put("data",data);
        return result;
    }

    /**
     * 获取几天前的时间
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d,int day){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE,now.get(Calendar.DATE)-day);
        return now.getTime();
    }

}
